%% More advanced reporting features in IRIS
% by Petar Manchev
%
% Create two more sophisticated reports: the first one showing how to
% format and modify graphs in reports, the other one showing how to format
% and modify tables.

%% Clear workspace

clear;
close all;
clc;
%#ok<*NOPTS>

%% More on figures in reports
%
% One can do many things with figures in IRIS reports: add subplots,
% legends, highlight certain periods (great for recession bars), add
% vertical lines, confidence bands, etc. The structure is hierarchical so 
% any property set at the figure level will apply to all its children 
% (graphs, series, etc.). The user can even pass a style structure at any
% of those levels which is an easy way to specify line thickness, color,
% whether the line is to be solid or dotted, etc.
%
% Comments on the code below:
%
% * <?sty?> The IRIS style structure is organized in close analogy with 
% Matlab's own hiearchical graphical language, both in terms of structure 
% and syntax. When multiple property values are specified, they are applied
% to the approriate objects in order of appearance - in this example, when
% plotting multiple lines the first one will be solid and 2-point wide,
% while the second will be 1.5-point wide and dashed.
%
% * <?subplot?> Notice that you do not have to populate all for slots of the
% 2x2 figure.
%
% * <?nosty?> You can "opt out" of the style on some children by passing an
% empty structure.
%
% * <?patch?> You can control the color of the confidence band in this way.
% The 3x1 vector encodes standard RGB color scheme intensities.
%
% * <?nosubplot?> You can actually omit the subplot option -- IRIS will
% automatically fit the number of graphs you declare in the smallest
% possible grid.
%
% * <?subtitle?> You can add subtitles in this fashion to any object in an 
% IRIS report.
%
% * <?legend?> This is how you can manipulate legend properties.
%
% * <?plotfunc?> As the name suggests, `plotfunc` allows the user to choose
% among several different plotting functions.
%
% * <?barcon?> The `barcon` function plots a multivariate `tseries` object as
% a stacked bar chart. This is a very useful type of chart in practice,
% because it is a visually appealing way to present decompositions of, for
% example, GDP forecasts into national account components. 
%
% * <?trick?> A nice thing to do with a `barcon` is to overlay the headline
% number you are decomposing as a line chart on top of it. To increase
% visibility, you can, for example, plot the same line twice, once wider
% and in white and a second time thinner and in another color. Note that
% passing $NaN$ to the `'legend'` option results in excluding the 'phantom'
% series from the list of legend entries.
%
% * <?display?> The option `'display'` controls if the LaTeX compiler
% message (quite extensive) is printed on the screen or not. It is good
% idea to keep it on (i.e. `'display'` set to true, which is the default)
% especially when you're building and debuggin a new report. We're turning
% it off here to suppress excessively long screen output in the tutorial
% pdf.

rng = mm(2000,1):mm(2010,11);
d = struct();
d.xx = tseries(rng,@rand);
d.zz = 100*diff(log(d.xx));
d.cc = cumsum(d.xx);
d.bb = 1/d.xx;

range = qq(2000,1):qq(2004,4);
d.x = cumsum(tseries(range,@randn)*0.03);

sty = struct(); %?sty?
sty.line.lineWidth = {2,1.5};
sty.line.lineStyle = {'-','-.'};
sty.axes.xgrid = 'off';
sty.axes.ygrid = 'off';
sty.legend.box = 'off'; %?legend?
sty.legend.location = 'northWest';
sty.vline.color = {'red',[0,0.5,0]};
sty.vlineCaption.color = {'red',[0,0.5,0]};
sty.vlineCaption.fontWeight = {'normal','bold'};
sty.highlight.faceColor = {[1,0.8,0.8],[0.8,0.8,1]};
sty.highlightCaption.color = 'black';

sty2 = struct;
sty2.vline.color = 'magenta';
sty2.vlineCaption.color = [1,0.5,0];
sty2.highlight.faceColor = [0.7,0.7,0.7];
sty2.highlightCaption.color = 'blue';

recess = {mm(2001,3):mm(2001,11),mm(2007,12):mm(2009,6)}; %?recess?

x = report.new('More on figures');

x.figure('Here is how you do subplots',...
    'range=',rng,...
    'subplot=',[2 2]); %?subplot?

    x.graph('Some series');
        x.series('',d.xx);
    x.graph('You can change the frequency','range',qq(2005,1):qq(2010,4));
        x.series('',convert(d.cc,'q'));
    x.graph('You can add two series in a graph','legend',true);
        x.series('One',d.zz);        
        x.series('Two',d.bb);
        
x.figure('Lets apply a style to this figure',...
    'range=',rng,...
    'subplot=',[2 2],...
    'style=',sty);

    x.graph('Some series','style',struct()); %?nosty?
        x.series('',d.xx);
    x.graph('You can change the frequency','range',qq(2005,1):qq(2010,4));
        x.series('',convert(d.cc,'q'));
    x.graph('You can add two series in a graph','legend',true);
        x.series('One',d.zz);        
        x.series('Two',d.bb);        
        
x.figure('Confidence bands','range',rng,'style',sty);
    x.graph('A very important series');
        x.band('',d.cc, ... % TODO: Comment on the confidence bands.
            [tseries(rng,-6),tseries(rng,-2)], ...
            [tseries(rng,+6),tseries(rng,+2)], ...
            'white=',[0.8,0.6]);
                
x.figure(...
    {'Vertical lines and highlighting',...
    'probably more than you want to know...'},... %?subtitle?
    'range=',range,'style=',sty); %?nosubplot?

    x.graph('Graph 1');
        x.series('',d.x);
        x.vline('\leftarrow This is 2001:4',qq(2001,4),'hPosition','right');
        x.vline('This is 2004:2 \rightarrow',qq(2004,2), ...
            'vPosition=','bottom','hPosition=','left');
        x.highlight('',qq(2000,3):qq(2002,1));
        x.highlight('\leftarrow Highlight \rightarrow', ...
            qq(2002,3):qq(2003,4), ...
            'vPosition=','middle','hPosition=','centre');

    x.graph('Graph 2');
        x.series('',d.x);
        x.vline(' You may wonder what this is \cdot\cdot\cdot',qq(2001,2), ...
            'vPosition=','middle','hPosition=','right');
        
    x.graph('Graph 3','style=',sty2,'hPosition=','left');
        x.series('',d.x);
        x.vline('But you ',qq(2001,1),'vPosition=',0.8);
        x.vline('certainly ',qq(2002,1),'vPosition=',0.6);
        x.vline('guess ',qq(2003,1),'vPosition=',0.4);
        x.vline('all these ',qq(2004,1),'vPosition=',0.2);
        x.highlight(' From a date to a date',qq(2000,3):qq(2003,2), ...
            'vPosition=',0.1,'hPosition=','left');

    x.graph({'Graph 4','subtitle'},... %?subtitle?
        'style=',sty2,'hPosition=','left');
        x.series('',d.x);
        x.highlight('Recession',{qq(2000,3:4),qq(2001,4):qq(2002,3),qq(2004,1)}, ...
            'hPosition=','center');       
        
x.figure('Bar charts and contribution charts',...
    'range=',range);

    x.graph('Graph 1');
        x.series('',d.x,'plotfunc=',@bar); %?plotfunc?

thissty = struct();
thissty.line.lineWidth = {3,1.5};
thissty.line.color = {[1 1 1],[0 0 0]}; 
thissty.axes.xgrid = 'off';
thissty.axes.ygrid = 'off';
        
    x.graph('Graph 2','legend',true,'style',thissty);
        x.series('',[d.x convert(d.xx,'q')],...
            'plotfunc=',@conbar,'legend=',{'x','xx'}); %?conbar?
        x.series('',d.x+convert(d.xx,'q'),'legend=',NaN); %?trick?
        x.series('Sum',d.x+convert(d.xx,'q'));

x
        
x.publish('report3.pdf','maketitle=',true,'display=',false); % ?display?

open report3.pdf;

%% More on tables and matrices in reports
%
% One of the greatest strengths of the IRIS `table` objects is the ability
% to conditionally format values based on user-specified 'tests'. Apart
% from that, you can easily display 2 sets of numbers for one series --
% ideal for showing headline values and shock-minus-control values from
% some baseline. Finally, you can also display mixed frequencies in one and
% the same table.
%
% To see the list of table or matrix attributes you can 'test' for 
% purposes of conditional formating, check out help on `report/series` or
% `report/matrix`.
%
% Comments on the code below:
%
% * <?last?> Last period scenario.
%
% * <?base?> Baseline scenario.
%
% * <?diff?> Database with two columns: Baseline and the difference between 
% baseline and last period scenario.
%
% * <?condFormat?> Specify conditional formatting. Passed to the `table` 
% object using the `'condFormat'` option. Note that if a particular entry 
% complies with two or more tests, the corresponding formats are all 
% applied (cumulated). 
%
% * <?test1?> Test 1 -- values smaller than 0.5.
%
% * <?test2?> Test 2 -- table rows under the heading 'XXX'.
%
% * <?test3?> Test 3 -- table rows whose marks contain 'Delta'.
%
% * <?mtest1?> Matrix Test 1 -- Highlight diagonal elements, i.e. test
% `row == col`.

d1.a = tseries(qq(2009,1):qq(2011,4),@rand); %?last?
d1.x = tseries(qq(2009,1):qq(2011,4),@rand);
d1.y = tseries(qq(2009,1):qq(2011,4),@rand);
d1.ylow  = d1.y - tseries(qq(2009,1):qq(2011,4),@rand);
d1.yhigh = d1.y + tseries(qq(2009,1):qq(2011,4),@rand);

d2.a = tseries(qq(2009,1):qq(2011,4),@rand); %?base?
d2.x = tseries(qq(2009,1):qq(2011,4),@rand);
d2.y = tseries(qq(2009,1):qq(2011,4),@rand);
d2.ylow  = d2.y - tseries(qq(2009,1):qq(2011,4),@rand);
d2.yhigh = d2.y + tseries(qq(2009,1):qq(2011,4),@rand);

d = dbfun(@(x,y) [y,y-x],d1,d2); %?diff?

x = report.new();

x.text();

%{
Conditional formatting: \par
In the following tables, there are two
conditional formats used:
(i) All values smaller than 0.5 are displayed red;
(ii) All values in rows under the heading 'XXX' are in italics;
(iii) Table rows marked with a delta sign, $\Delta$ (difference against the
last period scenario) are enclosed in square brackets.
%}

c = struct();
c(1).test   = 'value < 0.5'; %?test1?
c(1).format = '\color{red}';
c(2).test   = 'strcmp(text,''XXX'')'; %?test2?
c(2).format = '\mathit';
c(3).test   =  '~isempty(strfind(mark,''Delta''))'; %?test3?
c(3).format = '[?]';

x.table('Table with a classic date format', ...
   'range=',qq(2009,1):qq(2011,4), ...
   'dateFormat=','YYYY:P', ...
   'condFormat=',c, ... %?condFormat?
   'marks=',{'Baseline','{$\Delta$}'});

   x.series('AAA',d.a);
   x.series('XXX',d.x,'showMarks',false);
   %x.band('BBB',d.y,d.ylow,d.yhigh);

x.table('Table with a two-line date format', ...
   'range=',qq(2009,1):qq(2011,4), ...
   'dateFormat=',{'YYYY','FP'}, ...
   'condFormat=',c, ...
   'marks=',{'Baseline','{$\Delta$}'});

   x.series('AAA',d.a);
   x.series('XXX',d.x,'showMarks=',false);
   %x.subheading('This is a subheading')
   %x.series('BBB',d.y,d.ylow,d.yhigh);

c2 = struct();
c2.test   = 'col == row'; %?mtest1?
c2.format = '\colorbox{yellow}{?}';
   
x.matrix({'Highlight diagonal elements', ...
    'Test col == row'},...
    rand(10),...
    'rowNames=',{'aa','bb','xx','ee','ww','qq','rr','ss','pp','mm'},...
    'colNames=',{'qq','zz','ff','hh','bb','nn','jj','kk','ll','oo'},...
    'condFormat=',c2);

c3 = struct();
c3(1).test = 'value == max(rowvalues)';
c3(1).format = '\color{red}';
c3(2).test = 'value == max(max(allvalues))';
c3(2).format = '\colorbox{yellow}{?}';

x.matrix({'Highlight maximum on each row, and overall maximum', ...
    'Test value == max(rowvalues) and value == max(max(allvalues))'},...
    rand(10),...5
    'rowNames=',{'aa','bb','xx','ee','ww','qq','rr','ss','pp','mm'},...
    'colNames=',{'qq','zz','ff','hh','bb','nn','jj','kk','ll','oo'},...
    'condFormat=',c3);

x

x.publish('report4.pdf','display=',false);

open report4.pdf;

%% Help on IRIS functions used in this m-file
%
% Use either `help` to display help in the command window, or `idoc`
% to display help in an HTML browser window.
%
%    help report
%    help report/new
%    help report/publish
%    help report/table
%    help report/series
%    help report/figure
%    help report/graph
%    help report/matrix
%    help report/pagebreak
%    help report/text
